package com.knowledge.business.controller;

import com.knowledge.business.service.AliyunSttNewService;
import com.knowledge.business.service.AliyunSttOneService;
import com.knowledge.common.annotation.Anonymous;
import com.knowledge.common.core.domain.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import reactor.core.publisher.Sinks;
import reactor.core.publisher.Flux;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;


/**
 * 语音识别1111
 */
@RestController
@RequestMapping("/api/speech")
public class SpeechRecognitionController {

    @Autowired
    private AliyunSttNewService aliyunSttService;


    private static final String TEMP_DIR = System.getProperty("java.io.tmpdir") + "/speech_files/";

//    @PostMapping("/recognize")
//    public AjaxResult recognize(@RequestParam("audio") MultipartFile audioFile) {
//        try {
//            // 检查文件是否存在
//            if (audioFile.isEmpty()) {
//                return AjaxResult.error("文件不能为空");
//            }
//            // 添加调试信息
//            System.out.println("接收到音频文件大小: " + audioFile.getSize());
//            System.out.println("音频文件类型: " + audioFile.getContentType());
//            // 将MultipartFile转换为字节数组
//            byte[] audioData = audioFile.getBytes();
//
//            // 使用流式识别
//            Sinks.Many<byte[]> audioSink = Sinks.many().unicast().onBackpressureBuffer();
//
//            // 创建线程安全的结果引用和完成信号
//            AtomicReference<String> finalResult = new AtomicReference<>("");
//            CountDownLatch completionLatch = new CountDownLatch(1);
//
//            // 在新线程中发送音频数据
//            new Thread(() -> {
//                try {
//                    // 按块发送音频数据（模拟流式传输）
//                    int chunkSize = 3200; // 16000Hz * 2bytes * 0.1s = 3200 bytes per 100ms
//                    for (int i = 0; i < audioData.length; i += chunkSize) {
//                        int end = Math.min(i + chunkSize, audioData.length);
//                        byte[] chunk = new byte[end - i];
//                        System.arraycopy(audioData, i, chunk, 0, chunk.length);
//                        audioSink.tryEmitNext(chunk).orThrow();
//
//                        // 控制发送节奏
//                        Thread.sleep(100);
//                    }
//                    audioSink.tryEmitComplete().orThrow();
//                } catch (Exception e) {
//                    audioSink.tryEmitError(e);
//                }
//            }).start();
//
//            // 执行语音识别并等待结果
//            String result = aliyunSttService.streamRecognition(audioSink);
//            finalResult.set(result);
//            completionLatch.countDown(); // 设置完成信号
//
//            // 等待识别完成或超时
//            try {
//                if (!completionLatch.await(30, TimeUnit.SECONDS)) {
//                    System.out.println("语音识别超时");
//                }
//            } catch (InterruptedException e) {
//                Thread.currentThread().interrupt();
//                System.out.println("等待语音识别完成时被中断");
//            }
//
//            System.out.println("识别结果: " + finalResult.get());
//            return AjaxResult.success(finalResult.get());
//        } catch (IOException e) {
//            return AjaxResult.error("文件识别错误");
//        } catch (Exception e) {
//            return AjaxResult.error("文件识别错误");
//        }
//    }

    private static final Logger logger = LoggerFactory.getLogger(SpeechRecognitionController.class);

    /**
     * 一句话识别
     */
//    @PostMapping("/recognize")
//    public AjaxResult recognizeOne(@RequestParam("audio") MultipartFile audioFile) {
//        // 检查文件是否存在
//        if (audioFile.isEmpty()) {
//            return AjaxResult.error("音频文件不能为空");
//        }
//
//        // 检查文件类型（可选）
//        String contentType = audioFile.getContentType();
//        if (contentType == null || (!contentType.equals("audio/wav") && !contentType.equals("audio/x-wav"))) {
//            // 可以根据实际需求调整支持的音频格式
//            logger.warn("接收到的文件类型: {}", contentType);
//        }
//
//        String tempFilePath = null;
//        try {
//            // 生成唯一文件名
//            Path tempDirPath = Paths.get(TEMP_DIR);
//            if (!Files.exists(tempDirPath)) {
//                Files.createDirectories(tempDirPath);
//            }
//            String fileName = UUID.randomUUID().toString() + ".pcm";
//            Path tempFile = Paths.get(TEMP_DIR, fileName);
//            tempFilePath = tempFile.toString();
//
//            // 保存文件到临时目录
//            Files.copy(audioFile.getInputStream(), tempFile, StandardCopyOption.REPLACE_EXISTING);
//
//            // 创建语音识别服务实例
//            // 注意：在实际生产环境中，应该使用Spring的依赖注入来管理AliyunSttOneService实例
//            AliyunSttOneService speechService = new AliyunSttOneService(
//                    "cayHaQuXAOJyuB4g",
//                    "LTAI5tFSpEuFVeCj8CVqGFCU",
//                    "Vsvs9UcVfF1kiBL9LDthKg5WwP9aQS",
//                    ""
//            );
//
//            // 执行语音识别（假设上传的是16kHz PCM格式音频）
//            String result = speechService.process(tempFilePath, 16000);
//
//            // 关闭服务
//            speechService.shutdown();
//
//            // 删除临时文件
//            try {
//                Files.deleteIfExists(Paths.get(tempFilePath));
//            } catch (IOException e) {
//                logger.warn("删除临时文件失败: {}", tempFilePath, e);
//            }
//
//            return AjaxResult.success(result);
//
//        } catch (Exception e) {
//            logger.error("语音识别处理失败", e);
//
//            // 清理临时文件
//            if (tempFilePath != null) {
//                try {
//                    Files.deleteIfExists(Paths.get(tempFilePath));
//                } catch (IOException ex) {
//                    logger.warn("删除临时文件失败: {}", tempFilePath, ex);
//                }
//            }
//
//            return AjaxResult.error("语音识别失败: " + e.getMessage());
//        }
//    }
    @PostMapping("/recognize")
    @Anonymous
    public AjaxResult recognizeOne(@RequestParam("audio") MultipartFile audioFile) {
        // 检查文件是否存在
        if (audioFile.isEmpty()) {
            return AjaxResult.error("音频文件不能为空");
        }

        // 检查文件类型（可选）
        String contentType = audioFile.getContentType();
        if (contentType == null || (!contentType.equals("audio/wav") && !contentType.equals("audio/x-wav"))) {
            logger.warn("接收到的文件类型: {}", contentType);
        }

        try {
            // 直接使用字节数组进行识别，避免文件I/O操作
            byte[] audioData = audioFile.getBytes();
            AliyunSttOneService speechService = new AliyunSttOneService(
                    "cayHaQuXAOJyuB4g",
                    "LTAI5tFSpEuFVeCj8CVqGFCU",
                    "Vsvs9UcVfF1kiBL9LDthKg5WwP9aQS",
                    "");

            // 使用已注入的服务实例，避免重复创建
            String result = speechService.process(audioData, 16000);

            return AjaxResult.success(result);

        } catch (Exception e) {
            logger.error("语音识别处理失败", e);
            return AjaxResult.error("语音识别失败: " + e.getMessage());
        }
    }

    /**
     * 获取token
     *
     * @return
     * @throws IOException
     */
    @GetMapping("/getToken")
    @Anonymous
    public AjaxResult getToken() throws IOException {
        AliyunSttOneService aliyunSttService = new AliyunSttOneService();
        String token = aliyunSttService.getToken();
        return AjaxResult.success(token);
    }
}
